﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SlimDX.D3DCompiler;
using SlimDX;
using SlimDX.Direct3D11;
using SlimDX.DXGI;
using System.Runtime.InteropServices;
using Apparat.ShaderManagement;

namespace Apparat.Renderables
{
  public class LineStrip : Renderable
  {
    SlimDX.Direct3D11.Buffer vertexBuffer;
    DataStream vertices;

    int vertexStride;
    int numVertices;
    int vertexBufferSizeInBytes;

    System.Drawing.Color color = System.Drawing.Color.Black;

    public LineStrip(List<Vector3> points)
    {
      vertexStride = Marshal.SizeOf(typeof(Vector3)); // 12 bytes
      numVertices = points.Count;
      vertexBufferSizeInBytes = vertexStride * numVertices;

      vertices = new DataStream(vertexBufferSizeInBytes, true, true);

      foreach (Vector3 point in points)
      {
        vertices.Write(point);
      }

      vertices.Position = 0;

      vertexBuffer = new SlimDX.Direct3D11.Buffer(
         DeviceManager.Instance.device,
         vertices,
         vertexBufferSizeInBytes,
         ResourceUsage.Default,
         BindFlags.VertexBuffer,
         CpuAccessFlags.None,
         ResourceOptionFlags.None,
         0);

    }

    public void SetPoints(List<Vector3> points)
    {
      numVertices = points.Count;
      vertexBufferSizeInBytes = vertexStride * numVertices;

      vertices = new DataStream(vertexBufferSizeInBytes, true, true);

      foreach (Vector3 point in points)
      {
        vertices.Write(point);
      }

      vertices.Position = 0;

      vertexBuffer = new SlimDX.Direct3D11.Buffer(
         DeviceManager.Instance.device,
         vertices,
         vertexBufferSizeInBytes,
         ResourceUsage.Default,
         BindFlags.VertexBuffer,
         CpuAccessFlags.None,
         ResourceOptionFlags.None,
         0);
    }

    public void SetColor(System.Drawing.Color col)
    {
      color = col;
    }

    EffectWrapperTransformEffect ew = ShaderManager.Instance.transformEffect;

    public override void Render()
    {
      Matrix ViewPerspective = CameraManager.Instance.ViewPerspective;
      Matrix WorldViewPerspective = this.transform * ViewPerspective;
      ew.tmat.SetMatrix(WorldViewPerspective);

      ew.mCol.Set(new Color4(1, color.R / 255.0f, color.G / 255.0f, color.B / 255.0f));

      DeviceManager.Instance.context.InputAssembler.InputLayout = ew.layout;
      DeviceManager.Instance.context.InputAssembler.PrimitiveTopology = PrimitiveTopology.LineStrip;
      DeviceManager.Instance.context.InputAssembler.SetVertexBuffers(0, new VertexBufferBinding(vertexBuffer, vertexStride, 0));


      ew.technique = ew.effect.GetTechniqueByName("Render");

      EffectTechniqueDescription techDesc;
      techDesc = ew.technique.Description;

      for (int p = 0; p < techDesc.PassCount; ++p)
      {
        ew.technique.GetPassByIndex(p).Apply(DeviceManager.Instance.context);
        DeviceManager.Instance.context.Draw(numVertices, 0);
      }
    }

    public override Matrix Transform
    {
      get
      {
        return transform;
      }
      set
      {
        transform = value;
      }
    }

    public override void Dispose()
    {
      vertexBuffer.Dispose();
    }
  }
}
